package rhplus.utilizador;

import java.io.Serializable;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import javax.jdo.PersistenceManager;
import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;
import rhplus.acessoBD.PMF;
import rhplus.gestor.UtensiliosParaDatas;
import rhplus.persistencia.ContaDeUtilizador;
import rhplus.sistema.CodigoPostal;
import rhplus.sistema.Mensagem;

@PersistenceCapable
public class Colaborador implements Serializable{

    @PrimaryKey
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
    private Long id_pessoa;
    @Persistent
    private String tipo;
    @Persistent
    private String nib;
    @Persistent
    private String nss;
    @Persistent
    private Date data_admissao;
    @Persistent
    private double vencimento;
    @Persistent
    private Date validade_contrato;
    @Persistent
    private String horario_trabalho;
    @Persistent
    private Long id_hospital;
    @Persistent
    private String horario_trabalho2;
    @Persistent
    private Long id_hospital2;
    @Persistent
    private String especialidade;
    public static final String MEDICO = "medico";
    public static final String ENFERMEIRO = "enfermeiro";
    public static final String ADMINISTRATIVO = "administrativo";

    /** Creates a new instance of Colaborador */
    public Colaborador(final String nib, final String nss, final Date data_admissao, final double vencimento,
            final Date validade_contrato, final String horario_trabalho, final Long id_hospital, final String horario_trabalho2, final Long id_hospital2, String tipo, String especialidade) {

        this.nib = nib;
        this.nss = nss;
        this.data_admissao = data_admissao;
        this.vencimento = vencimento;
        this.validade_contrato = validade_contrato;
        this.horario_trabalho = horario_trabalho;
        this.id_hospital = id_hospital;
        this.horario_trabalho2 = horario_trabalho2;
        this.id_hospital2 = id_hospital2;
        this.tipo = tipo;
        this.especialidade = especialidade;
    }

    public static void altera(Colaborador dados_do_colaborador) {
        PersistenceManager pm = PMF.get().getPersistenceManager();
        try {
            pm.currentTransaction().begin();
            // We don't have a reference to the selected Product.
            // So we have to look it up first,
            Colaborador p = pm.getObjectById(Colaborador.class, dados_do_colaborador.getIdPessoa());

            p.setAll(dados_do_colaborador);
            pm.makePersistent(dados_do_colaborador);
            pm.currentTransaction().commit();
        } catch (Exception ex) {
            pm.currentTransaction().rollback();
            throw new RuntimeException(ex);
        } finally {
            pm.close();
        }
    }

    public static Pessoa devolve(String username) {
        PersistenceManager pm = PMF.get().getPersistenceManager();

        String query = "select from " + ContaDeUtilizador.class.getName()
                + " where username == '" + username + "'";

        Long id_pessoa = ((List<ContaDeUtilizador>) pm.newQuery(query).execute()).get(0).getIdPessoa();

        query = "select from " + Pessoa.class.getName()
                + " where id_pessoa == " + id_pessoa;
        Pessoa p = ((List<Pessoa>) pm.newQuery(query).execute()).get(0);

        return p;
    }

    public Long getIdPessoa() {
        return id_pessoa;
    }

    public void setIdPessoa(Long idp) {
        this.id_pessoa = idp;
    }

    public String getNib() {
        return nib;
    }

    public String getNss() {
        return nss;
    }

    public String getTipo() {
        return tipo;
    }

    public Date getDataAdmissao() {
        return data_admissao;
    }

    public double getVencimento() {
        return vencimento;
    }

    public Date getValidadeContrato() {
        return validade_contrato;
    }

    public String getHorarioTrabalho() {
        return horario_trabalho;
    }

    public Long getIdHospital() {
        return id_hospital;
    }

    public String getHorarioTrabalho2() {
        return horario_trabalho2;
    }

    public Long getIdHospital2() {
        return id_hospital2;
    }

    public String getEspecialidade() {
        return especialidade;
    }


    public static Colaborador devolvePorIdPessoa(Long id_pessoa) {

        PersistenceManager pm = PMF.get().getPersistenceManager();

        String query = "select from " + Colaborador.class.getName()
                + " where id_pessoa == " + id_pessoa;

        List<Colaborador> u = (List<Colaborador>) pm.newQuery(query).execute();

        return u.get(0);
    }

    public String getHorarioTrabalhoParaHospital(final Long id_hospital) {
        String devolver = "";

        if (id_hospital == getIdHospital()) {
            devolver = getHorarioTrabalho();
        }
        if (id_hospital == getIdHospital2()) {
            devolver = getHorarioTrabalho2();
        }

        return devolver;
    }

    public static void insereEnfermeiro(final Colaborador colaborador) {

        PersistenceManager pm = PMF.get().getPersistenceManager();

        try {
            pm.makePersistent(colaborador);
        } finally {
            pm.close();
        }
    }

    public static void insere(Pessoa pessoa, Colaborador colaborador, ContaDeUtilizador conta) {
        // isere na tabela pessoa
        Pessoa.insere(pessoa);
        Long id_p = Pessoa.devolveIdPessoaPorBI(pessoa.getBI());

        // insere na tabela colaborador
        colaborador.setIdPessoa(id_p);
        insereColaborador(colaborador);

        // insere na tabela conta utilizador
        conta.setIdPessoa(id_p);
        conta.setPerfil(colaborador.getTipo());
        ContaDeUtilizador.insere(conta);
    }

    public static void insereColaborador(Colaborador colaborador) {
        PersistenceManager pm = PMF.get().getPersistenceManager();

        try {
            pm.makePersistent(colaborador);
        } finally {
            pm.close();
        }
    }

    public static List<Colaborador> devolveTodos() {

        PersistenceManager pm = PMF.get().getPersistenceManager();

        String query = "select from " + Colaborador.class.getName();

        List<Colaborador> lista_de_colaboradores = (List<Colaborador>) pm.newQuery(query).execute();

        return lista_de_colaboradores;
    }

    public void setAll(Colaborador u) {
        this.nib = u.getNib();
        this.nss = u.getNss();
        this.data_admissao = u.getDataAdmissao();
        this.vencimento = u.getVencimento();
        this.validade_contrato = u.getValidadeContrato();
        this.horario_trabalho = u.getHorarioTrabalho();
        this.horario_trabalho2 = u.getHorarioTrabalho2();
    }

    public static void remove(final Long id_pessoa) {

        PersistenceManager pm = PMF.get().getPersistenceManager();

        try {
            pm.currentTransaction().begin();

            Colaborador colaborador = pm.getObjectById(Colaborador.class, id_pessoa);

            pm.deletePersistent(colaborador);

            pm.currentTransaction().commit();

        } catch (Exception ex) {
            pm.currentTransaction().rollback();
            throw new RuntimeException(ex);
        } finally {
            pm.close();
        }

    }

    public static LinkedList<String> verificaMensagens(final Long id_pessoa) {

        LinkedList<String> lista_mensagens = new LinkedList<String>();

        PersistenceManager pm = PMF.get().getPersistenceManager();

        String query = "select from " + Mensagem.class.getName() + " where id_pessoa == " + id_pessoa;

        List<Mensagem> lista = (List<Mensagem>) pm.newQuery(query).execute();

        for (Mensagem m : lista) {
            lista_mensagens.add(m.getTexto());
        }

        return lista_mensagens;
    }

    public static void cancelaContracto(final Long id_colaborador, final Date data_recisao, final String motivo) {

        PersistenceManager pm = PMF.get().getPersistenceManager();
        try {
            pm.currentTransaction().begin();
            Pessoa p = pm.getObjectById(Pessoa.class, id_colaborador);
            String nome = p.getNome();
            nome +="CONTRATOEXPIRADO";
            p.setNome(nome);
            pm.makePersistent(p);
            pm.currentTransaction().commit();
        } catch (Exception ex) {
            pm.currentTransaction().rollback();
            throw new RuntimeException(ex);
        }
        
        try {
            pm.currentTransaction().begin();
            Colaborador c = pm.getObjectById(Colaborador.class, id_colaborador);
            c.setDataRecisao(data_recisao);
            pm.makePersistent(c);
            pm.currentTransaction().commit();
        } catch (Exception ex) {
            pm.currentTransaction().rollback();
            throw new RuntimeException(ex);
        } finally {
            pm.close();
        }

        String cancela = "Contrato Expirado\n Motivo: "+motivo;

        Mensagem.adicionaNova(cancela,id_colaborador);
    }

//    public static String devolveHorariosDeTrabalho() {
//
//        String query = "select from " + Colaborador.class.getName();
//        PersistenceManager pm = PMF.get().getPersistenceManager();
//        List<Colaborador> lista_de_horarios_de_trabalho = (List<Colaborador>) pm.newQuery(query).execute();
//
//        return lista_de_horarios_de_trabalho.get(0).;
//
//    }
//    public static LinkedList<String> converteHorarios(final String horarios) {
//        /*  LinkedList<String> lista_de_horarios = new LinkedList<String>();
//        String regex = "\\d{1,2}:\\d{2}-\\d{1,2}:\\d{2}";
//        Pattern pattern = Pattern.compile(regex);
//        Matcher matcher = pattern.matcher(horarios);
//        while (matcher.find()) {
//        int start = matcher.start();
//        int end = matcher.end();
//        lista_de_horarios.add(horarios.substring(start, end));
//        }
//        return lista_de_horarios;*/
//    }
//
//    public static LinkedList<String> converteEspecialidades(final String especialidades) {
//        /*    LinkedList<String> lista_de_especialidades = new LinkedList<String>();
//        String regex = "\\d{1,2}:\\d{2}-\\d{1,2}:\\d{2}";
//        Pattern pattern = Pattern.compile(regex);
//        Matcher matcher = pattern.matcher(especialidades);
//        while (matcher.find()) {
//        int start = matcher.start();
//        int end = matcher.end();
//        lista_de_especialidades.add(especialidades.substring(start, end));
//        }
//        return lista_de_especialidades;*/
//    }
//
    public static List<String> devolveTodasAsEspecialidades() {
        String query = "select from " + Colaborador.class.getName();
        PersistenceManager pm = PMF.get().getPersistenceManager();
        List<Colaborador> lista = (List<Colaborador>) pm.newQuery(query).execute();
        LinkedList<String> esp = new LinkedList<String>();
        for (Colaborador c : lista) {
            if (c.getEspecialidade() != null) {
                esp.add(c.getEspecialidade());
            }
        }
        return esp;
    }

    public static void addAdmin() {
        //final String nome, final char sexo, final int bi,
        //final Date data_de_nascimento, final int nif, final String email, final int telefone,
        //final int telemovel, final String morada, final String grupo_sanguineo, final Long codigo_postal
        CodigoPostal cod = new CodigoPostal(9999, 999, "administraçao");
        CodigoPostal.insere(cod);
        Long codigo = CodigoPostal.devolve(9999, 999).getIdCodigoPostal();
        Date dat = UtensiliosParaDatas.devolveDataEmDate("1970-01-01");
        Pessoa nova_pessoa = new Pessoa("Administrador", 'M', 000000000, dat, 000000000, "admim@admim.pt", 000000000,
                000000000, "morada", "O+", codigo);

        //final String nib, final String nss, final Date data_admissao, final double vencimento,
        //final Date validade_contrato, final String horario_trabalho, final Long id_hospital,
        //final String horario_trabalho2, final Long id_hospital2, String tipo, String especialidade
        Date da = UtensiliosParaDatas.devolveDataEmDate("1990-01-01");
        Date d = UtensiliosParaDatas.devolveDataEmDate("2020-01-01");
        Colaborador novo_colaborador = new Colaborador("000000000000000000000", "000000000", da, 1000.0, da, null,
                Long.MIN_VALUE, null, Long.MIN_VALUE, "Administrador", null);

        //final String username, final String password, final String estado
        ContaDeUtilizador nova_conta;
        nova_conta = new ContaDeUtilizador("admin1", "5f4dcc3b5aa765d61d8327deb882cf99", "1");
        Colaborador.insere(nova_pessoa, novo_colaborador, nova_conta);
    }

    @Override
    public String toString() {
        String colaborador_em_string = super.toString();

        return colaborador_em_string + ";" + nib + ";" + nss + ";" + data_admissao + ";" + vencimento + ";"
                + validade_contrato + ";" + horario_trabalho + ";" + id_hospital + ";" + horario_trabalho2 + ";" + id_hospital2 + ";";
    }

    private void setDataRecisao(Date data_recisao) {
        this.validade_contrato = data_recisao;
    }
}
